package com.gdiss.www.service.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gdiss.www.entity.User;
import com.gdiss.www.service.TokenService;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Velore
 * @date 2022/1/20
 **/
@Service
public class JwtTokenServiceImpl implements TokenService {

    /**
     * 单位：天
     */
    public static final int CALENDAR_FIELD = Calendar.DATE;

    /**
     * token 过期时间: 7天
     */
    public static final int CALENDAR_INTERVAL = 7;

    /**
     * token密钥
     */
    public static final String SECRET = "token secret service";

    @Override
    public String generate(User user){
        // 获取过期时间
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(CALENDAR_FIELD, CALENDAR_INTERVAL);
        Date expiresDate = nowTime.getTime();

        // 头信息
        Map<String, Object> map = new HashMap<>(2);
        map.put("alg", "HS256");
        map.put("typ", "JWT");

        return JWT.create().withHeader(map)
                //token的签发证明人
                .withIssuer("SERVICE")
                //token的有效持有者
                .withAudience(String.valueOf(user.getId()))
                //token签发的时间
                .withIssuedAt(Calendar.getInstance().getTime())
                //token过期的时间
                .withExpiresAt(expiresDate)
                .sign(Algorithm.HMAC256(SECRET));
    }

    @Override
    public String refresh(String token) {
        DecodedJWT jwt = JWT.decode(token);
        User user = new User();
        user.setId(Integer.parseInt(jwt.getAudience().get(0)));
        return generate(user);
    }

    @Override
    public void verify(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            verifier.verify(token);
        } catch (JWTVerificationException e) {
            throw new RuntimeException("token已失效");
        }
    }

    @Override
    public String getTokenId(String token){
        if(token == null || token.isEmpty()) {
            return "";
        }
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getAudience().get(0);
    }
}
